package com.juxing.service.accountCenter.impl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.juxing.sdk.util.DigestUtil;
import com.juxing.sdk.util.RandUtil;
import com.juxing.sdk.util.StringUtil;
import com.juxing.service.accountCenter.IAccountCenterService;
import com.juxing.service.accountCenter.bean.UserAccessTokenBean;
import com.juxing.service.accountCenter.bean.UserAccountBean;
import com.juxing.service.accountCenter.bean.UserPasswordBean;
import com.juxing.service.accountCenter.cache.IUserAccountCache;
import com.juxing.service.accountCenter.dao.IUserAccountDao;
import com.juxing.service.accountCenter.dao.IUserAccountMobileDao;

/**
 * 
 * @author brochen
 * @mail mongibello@163.com
 * @created 2016年1月31日
 *
 */
public class AccountCenterServiceImpl implements IAccountCenterService {

	private static final Logger logger = LoggerFactory.getLogger(AccountCenterServiceImpl.class);

	@Autowired
	private IUserAccountDao userAccountDao;
	@Autowired
	private IUserAccountMobileDao userAccountMobileDao;
	@Autowired
	private IUserAccountCache userAccountCache;
	
	private static final long ACCESS_TOKEN_EXPIRE = 15L * 24 * 3600 * 1000;//ACCESS_TOKEN过期时间
	
	/**
	 * 通过手机号注册
	 * @param mobile
	 * @param password
	 * @return 
	 */
	public UserAccessTokenBean regByMobile(String mobile, String password) {
		long currTime = System.currentTimeMillis();
		logger.debug("regByMobile.mobile={}, password={}", mobile, password);
		
		//先查一下该手机是否已经注册了
		int userId = this.queryUserIdByMobile(mobile);
		if(userId > 0) {//原来已经生成过账号
			UserAccessTokenBean bean = this.queryUserAccountByUserId(userId);
			if(bean != null) {//上次注册只生成了账号
				this.updateUserPassword(userId, password);
				return this.updateAccessToken(userId);
			}
		} else {//生成账号
			userId = userAccountDao.generateUserId();
		}
		
		userAccountMobileDao.insert(userId, mobile);
		userAccountCache.setUserIdAndMobile(userId, mobile);
		
		String salt = RandUtil.getRandString(6);
		password = mixPassword(password, salt);
		UserAccountBean bean = new UserAccountBean();
		bean.setUserId(userId);
		bean.setPassword(password);
		bean.setSalt(salt);
		bean.setAccessToken(RandUtil.getRandString(16));
		bean.setLastPwdUpdateTime(currTime);
		bean.setAccessTokenExpireAt(currTime + ACCESS_TOKEN_EXPIRE);
		userAccountDao.insert(bean);
		
		UserPasswordBean upBean = new UserPasswordBean();
		upBean.setUserId(userId);
		upBean.setSalt(salt);
		upBean.setPassword(password);
		userAccountCache.setUserPasswordBean(upBean);
		
		UserAccessTokenBean uatBean = new UserAccessTokenBean();
		uatBean.setUserId(userId);
		uatBean.setAccessToken(bean.getAccessToken());
		uatBean.setAccessTokenExpireAt(currTime + ACCESS_TOKEN_EXPIRE);
		
		return uatBean;
	}
	/**
	 * 通过用户ID查找手机号
	 * @param userId
	 * @return
	 */
	public UserAccessTokenBean queryUserAccountByUserId(int userId) {
		UserAccessTokenBean bean = userAccountCache.getUserAccessTokenBean(userId);
		if(bean == null) {
			UserAccountBean uaBean = userAccountDao.queryByUserId(userId);
			if(uaBean != null) {
				bean = new UserAccessTokenBean();
				bean.setUserId(userId);
				bean.setAccessToken(uaBean.getAccessToken());
				bean.setAccessTokenExpireAt(uaBean.getAccessTokenExpireAt());
				userAccountCache.setUserAccessTokenBean(bean);
			}
		}
		return bean;
	}
	
	@Override
	public int queryUserIdByMobile(String mobile) {
		int userId = userAccountCache.getUserId(mobile);
		if(userId <= 0) {
			userId = userAccountMobileDao.queryUserId(mobile);
			if(userId > 0) {
				userAccountCache.setUserIdAndMobile(userId, mobile);
			}
		}
		return userId;
	}
	@Override
	public String queryMobileByUserId(int userId) {
		String mobile = userAccountCache.getMobile(userId);
		if(StringUtil.isEmpty(mobile)) {
			mobile = userAccountMobileDao.queryMobile(userId);
			if(!StringUtil.isEmpty(mobile)) {
				userAccountCache.setUserIdAndMobile(userId, mobile);
			}
		}
		return mobile;
	}
	@Override
	public void updateUserPassword(int userId, String password) {
		
		String salt = RandUtil.getRandString(6);
		password = mixPassword(password, salt);
		
		//更新数据库
		UserAccountBean uaBean = new UserAccountBean();
		uaBean.setUserId(userId);
		uaBean.setPassword(password);
		uaBean.setSalt(salt);
		uaBean.setLastPwdUpdateTime(System.currentTimeMillis());
		userAccountDao.updatePassword(uaBean);
		
		//更新缓存
		UserPasswordBean bean = new UserPasswordBean();
		bean.setUserId(userId);
		bean.setSalt(salt);
		bean.setPassword(password);
		userAccountCache.setUserPasswordBean(bean);
		
	}
	@Override
	public UserPasswordBean queryUserPasswordBean(int userId) {
		UserPasswordBean bean = userAccountCache.getUserPasswordBean(userId);
		if(bean == null) {
			UserAccountBean uaBean = userAccountDao.queryByUserId(userId);
			if(uaBean != null) {
				bean = new UserPasswordBean();
				bean.setUserId(userId);
				bean.setSalt(uaBean.getSalt());
				bean.setPassword(uaBean.getPassword());
				userAccountCache.setUserPasswordBean(bean);
			}
		}
		return bean;
	}
	
	@Override
	public boolean checkUserPassword(int userId, String password) {
		UserPasswordBean bean = this.queryUserPasswordBean(userId);
		if(bean == null) {
			return false;
		}
		String mixedPassword = this.mixPassword(password, bean.getSalt());
		if(StringUtil.isNotEmpty(mixedPassword) && mixedPassword.equals(bean.getPassword())) {
			return true;
		}
		return false;
	}
	
	@Override
	public UserAccessTokenBean updateAccessToken(int userId) {
		//更新accessToken
		long currTime = System.currentTimeMillis();
		UserAccountBean bean = new UserAccountBean();
		bean.setUserId(userId);
		bean.setAccessToken(RandUtil.getRandString(16));
		bean.setAccessTokenExpireAt(currTime + ACCESS_TOKEN_EXPIRE);
		userAccountDao.updateAccessToken(bean);
	
		//更新缓存
		UserAccessTokenBean uatBean = new UserAccessTokenBean();
		uatBean.setUserId(userId);
		uatBean.setAccessToken(bean.getAccessToken());
		uatBean.setAccessTokenExpireAt(currTime + ACCESS_TOKEN_EXPIRE);
		userAccountCache.setUserAccessTokenBean(uatBean);
		
		return uatBean;
	}
	
	/**
	 * 混淆密码
	 * @param originPassword
	 * @param salt
	 * @return
	 */
	private String mixPassword(String originPassword, String salt) {
		return DigestUtil.encryptMd5(DigestUtil.encryptMd5(originPassword) + DigestUtil.encryptMd5(salt));
	}
}
